#include "Moveable.h"
#include <QWidget>

Moveable::Moveable(QWidget *trigger, QWidget *mover, QObject *parent) : QObject(parent)
{
    _trigger = trigger;
    _mover = nullptr==mover?trigger->window():mover;
    _isEnabled = false;
    _isMousePressed = false;
    setEnabled(true);
}

void Moveable::setEnabled(bool enable){
    if(_isEnabled == enable){
        return;
    }
    _isEnabled = enable;

}
void Moveable::setPadding(int padding){
    _topPadding=_leftPadding=_bottomPadding=_rightPadding = padding;
}
void Moveable::setPadding(int top, int left, int bottom, int right){
    _topPadding=top;
    _leftPadding=left;
    _bottomPadding=bottom;
    _rightPadding = right;
}

bool Moveable::eventFilter(QObject *w, QEvent *e){
    QWidget *ww = qobject_cast<QWidget*>(w);
    if(nullptr==ww || ww!=_trigger){
        return QObject::eventFilter(w,e);
    }

    if(e->type()==QEvent::MouseMove){
        QMouseEvent *me = static_cast<QMouseEvent*>(e);
        onMoveEvent(me);
    }
    else if(e->type()==QEvent::MouseButtonPress){
        QMouseEvent *me = static_cast<QMouseEvent*>(e);
        onPressEvent(me);
    }
    else if(e->type()==QEvent::MouseButtonRelease){
        QMouseEvent *me = static_cast<QMouseEvent*>(e);
        onReleaseEvent(me);
    }
    else if(e->type()==QEvent::MouseButtonDblClick){
        QMouseEvent *me = static_cast<QMouseEvent*>(e);
        onDoubleClickEvent(me);
    }
    else{

    }
    return QObject::eventFilter(w,e);
}
void Moveable::onMoveEvent(QMouseEvent *event){
    if (!_isMousePressed){
        return;
    }

    /* FIXME: target has parent or no has parent */
    QPoint dPos = event->globalPos() - _posPressed;
    if (dPos.manhattanLength() > 5){
        QWidget *target = nullptr==_mover?_trigger:_mover;
        target->move(dPos);
    }
}
void Moveable::onPressEvent(QMouseEvent *event){
    QWidget *target = nullptr==_mover?_trigger:_mover;
    _posPressed = event->pos();
    if (nullptr != target->childAt(_posPressed))
    {
        QString className = target->childAt(_posPressed)->metaObject()->className();
        if ("QSpinBox" == className || "QDoubleSpinBox" == className
            || "QTimeEdit" == className || "QDateEdit" == className || "QDateTimeEdit" == className
            || "QtCharts::GLWidget" == className)
            return;
    }

    QRect rect(_leftPadding,_topPadding,target->width()-_leftPadding-_rightPadding,target->height()-_topPadding-_bottomPadding);
    if (Qt::LeftButton == event->button() && rect.contains(_posPressed) && target->windowState()&Qt::WindowState::WindowMaximized){
        _isMousePressed = true;
    }
}
void Moveable::onReleaseEvent(QMouseEvent *event){
    Q_UNUSED(event);
    _isMousePressed = false;
}
void Moveable::onDoubleClickEvent(QMouseEvent *event){
    QWidget *target = nullptr==_mover?_trigger:_mover;
    _posPressed = event->pos();
    QRect rect(_leftPadding,_topPadding,target->width()-_leftPadding-_rightPadding,target->height()-_topPadding-_bottomPadding);
    if (Qt::LeftButton == event->button() && rect.contains(_posPressed))
    {
        Qt::WindowStates states = target->windowState();
        if(states & Qt::WindowState::WindowNoState){
            target->showMaximized();
        }
        else{
            target->showNormal();
        }
    }
}
